package com.mach.platform.security;

import com.alibaba.fastjson.JSON;
import com.google.code.kaptcha.Constants;
import com.google.common.collect.Maps;
import com.mach.platform.exception.KaptchaException;
import lombok.Cleanup;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

/**
 * @author Anonymous
 * @Description:  验证码过滤器
 * @Package: com.mach.platform.security
 * @Time create on 2017/11/28 22:49
 */
public class KaptchaAuthenticationFilter extends AbstractAuthenticationProcessingFilter{

	private String defaultFilterProcessesUrl;

	public static final String VERIFY_CODE = "verification";

	public KaptchaAuthenticationFilter(String defaultFilterProcessesUrl) {
		super(defaultFilterProcessesUrl);
		this.defaultFilterProcessesUrl = defaultFilterProcessesUrl;

	}

	@Override
	public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
			throws IOException, ServletException {

		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;

		if (HttpMethod.POST.name().equalsIgnoreCase(request.getMethod()) && defaultFilterProcessesUrl.equals(request.getServletPath())) {

			String sessionCode = obtainSessionVerifyCode(request,response);
			String requestCode = obtainVerifyCode(request);

			if (requestCode != null && !sessionCode.equalsIgnoreCase(requestCode)) {

//				unsuccessfulAuthentication(request, response, new KaptchaException("输入的验证码不正确"));
				response.setContentType("application/json;charset=utf-8");
				@Cleanup PrintWriter out = response.getWriter();
				Map map = Maps.newHashMap();
				map.put("status", HttpStatus.NOT_ACCEPTABLE.value());
				map.put("msg", "输入的验证码不正确");
				out.write(JSON.toJSON(map).toString());

				return;
			}

		}

		chain.doFilter(req, res);
	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException, IOException, ServletException {
		return null;
	}

	/**
	 * 获取请求中的 验证码
	 *
	 * @param request
	 * @return
	 */
	protected String obtainVerifyCode(HttpServletRequest request) {
		return request.getParameter(VERIFY_CODE).toString();
	}

	protected String obtainSessionVerifyCode(HttpServletRequest request,HttpServletResponse response)
			throws IOException {

		if (request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY) == null) {

			response.setContentType("application/json;charset=utf-8");
			@Cleanup PrintWriter out = response.getWriter();
			Map map = Maps.newHashMap();
			map.put("status", HttpStatus.NOT_ACCEPTABLE.value());
			map.put("msg", "验证码过期，需要刷新！");
			out.write(JSON.toJSON(map).toString());

			throw new KaptchaException("验证码过期，需要刷新！");
		}


		return request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY).toString();
	}

}
